package PrjDBUtils

import (
	"dgo/goutils/utils"
	"fmt"
	"time"
)

var (
	db_queue_lst utils.GSyncMapGroup
)

type db_queue_task_rec struct {
	id          interface{}
	dsid        string
	task        *utils.QueueTask
	lastWarning string
}

func (this *db_queue_task_rec) stopTask() {
	this.task.Stop()
}

func (this *db_queue_task_rec) checkStartTask() {
	this.task = utils.NewQueueTaskFunc()
	this.task.ConfigIntervalCallBack(time.Second*5, func() {
		var dao *DAOHelper

		defer func() {
			if dao != nil {
				dao.Close()
			}
		}()

		// 从队列中最多取1024 跳SQL出来
		this.task.PopTaskArgMaxFunc(1024, func(args ...interface{}) bool {
			if dao == nil {
				dao = NewDAOHelper(this.dsid)
				err := dao.PrepareDBConn()
				if err != nil {
					this.lastWarning = fmt.Sprintf("[%s]连接数据库异常:%s", utils.NowString(), err.Error())
					return false
				}
			}

			lvsql := args[0].(string)
			upcnt, _, err := dao.ExecSQL(lvsql)
			if err != nil {
				this.lastWarning = fmt.Sprintf("[%s]sql:%s, err:%s", utils.NowString(), lvsql, err.Error())
			}

			if len(args) > 1 {
				v1 := args[1]
				if fn, ok := v1.(func(upcnt int64, err error)); ok {
					fn(upcnt, err)
				}
			}
			return true
		})
	})
}

func CheckStartDBQueueEx(dbid string) {
	CheckStartDBQueue(dbid, dbid)
}

func GetDBQueueStatus(id interface{}) string {
	v1 := db_queue_lst.Get(id, nil)
	if v1 == nil {
		return ""
	}
	qs := v1.(*db_queue_task_rec)
	return qs.task.String()
}

func CheckStartDBQueue(dbid string, id interface{}) {
	if id == nil {
		id = dbid
	}
	v1, loaded := db_queue_lst.LoadOrStoreFunc2(id, func() interface{} {
		rval := &db_queue_task_rec{id: id, dsid: dbid}
		rval.checkStartTask()
		return rval
	}, func(val interface{}) {
		l1 := val.(*utils.QueueTask)
		l1.Stop()
	})
	if !loaded {
		qs := v1.(*db_queue_task_rec)
		// 队列工作者最多3个
		qs.task.ConfigWorkNum(1, 4)
		qs.task.ConfigMaxQueueSize(8192)
		qs.task.Start()
	}
}

func ConfigDBQueue(id interface{}, min_worker_num, max_worker_num, max_queuesize int) error {
	v1 := db_queue_lst.Get(id, nil)
	if v1 == nil {
		return fmt.Errorf("[%v]DBQueueTask队列尚未创建", id)
	}
	qs := v1.(*db_queue_task_rec)
	// 队列工作者最多3个
	qs.task.ConfigWorkNum(int32(min_worker_num), int32(max_worker_num))
	qs.task.ConfigMaxQueueSize(max_queuesize)
	return nil
}

func RemoveDBQueue(id interface{}) error {
	v1 := db_queue_lst.Get(id, nil)
	if v1 == nil {
		return fmt.Errorf("[%v]DBQueueTask队列尚未创建", id)
	}
	qs := v1.(*db_queue_task_rec)
	qs.stopTask()
	db_queue_lst.Remove(id)
	return nil
}

func PostDBQueueTaskSQL(id interface{}, sql string) error {
	v1 := db_queue_lst.Get(id, nil)
	if v1 == nil {
		return fmt.Errorf("[%v]DBQueueTask队列尚未创建", id)
	}
	qs := v1.(*db_queue_task_rec)
	qs.task.Push(sql)
	return nil
}

func PostDBQueueTaskSQLEx(id interface{}, sql string, cb func(upcnt int64, err error)) error {
	v1 := db_queue_lst.Get(id, nil)
	if v1 == nil {
		return fmt.Errorf("[%v]DBQueueTask队列尚未创建", id)
	}
	qs := v1.(*db_queue_task_rec)
	if cb != nil {
		qs.task.Push(sql, cb)
	} else {
		qs.task.Push(sql)
	}

	return nil
}
